home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 May: Tool Chest / Dev.CD May 97 TC.toast / Sample Code / Snippets / Files / Keith's CatSearch / CatSearch.c next >
Encoding:
C/C++ Source or Header  |  1995-02-15  |  15.4 KB  |  682 lines  |  [TEXT/KAHL]

  1. #include "CatSearch.h"
  2.  
  3. #include <stdlib.h>        // bsearch
  4. #include <stdarg.h>
  5.  
  6. #define NIL nil
  7.  
  8. void    AddDirectoryTreeToList(short vRefNum, long parID, Handle list);
  9. void    AddDirectoryToList(long, Handle);
  10. Boolean    IsDirectoryInList(long, Handle);
  11. int        DirIDCompare(const void* key, const void* data);
  12.  
  13. OSErr
  14. PBCatSearchIn(CSParamPtr pb, long parID)
  15. {
  16.     OSErr    err;
  17.     long    loopy;
  18.     long    recordsToMove;
  19.     
  20.     static    long    lastParID = 0;
  21.     static    Handle    goodList = NIL;
  22.     
  23.     if (lastParID != parID)
  24.     {
  25.         unsigned long startTime, endTime;
  26.         lastParID = parID;
  27.  
  28.         if (goodList)
  29.             SetHandleSize(goodList, 0);
  30.         else
  31.             goodList = NewHandle(0);
  32.  
  33.         AddDirectoryTreeToList(pb->ioVRefNum, parID, goodList);
  34.     }
  35.  
  36.     err = PBCatSearchSync (pb);
  37.     
  38.     //
  39.     // Count downwards so that, as we remove unwanted records, we aren't
  40.     // moving forward records that we'll eventually be deleting.
  41.     //
  42.     for (loopy = pb->ioActMatchCount - 1; loopy >= 0; --loopy)
  43.     {
  44.         if (!IsDirectoryInList(pb->ioMatchPtr[loopy].parID, goodList))
  45.         {
  46.             recordsToMove = (pb->ioActMatchCount - 1) - loopy;
  47.             if (recordsToMove > 0)
  48.             {
  49.                 BlockMove(    &pb->ioMatchPtr[loopy + 1],
  50.                             &pb->ioMatchPtr[loopy],
  51.                             recordsToMove * sizeof(FSSpec));
  52.             }
  53.         
  54.             pb->ioActMatchCount--;
  55.         }
  56.     }
  57.  
  58.     return err;
  59. }
  60.  
  61. void
  62. AddDirectoryTreeToList(short vRefNum, long parID, Handle list)
  63. {
  64.     CInfoPBRec    pb;
  65.     long        index = 1;
  66.     OSErr        err;
  67.  
  68.     AddDirectoryToList(parID, list);
  69.     
  70.     pb.hFileInfo.ioNamePtr = NIL;
  71.     pb.hFileInfo.ioVRefNum = vRefNum;
  72.  
  73.     do {
  74.         pb.hFileInfo.ioDirID = parID;
  75.         pb.hFileInfo.ioFDirIndex = index++;
  76.         
  77.         err = PBGetCatInfoSync(&pb);
  78.         if (err == noErr)
  79.         {
  80.             if ((pb.hFileInfo.ioFlAttrib & ioDirMask) != 0)
  81.             {
  82.                 AddDirectoryTreeToList(vRefNum, pb.hFileInfo.ioDirID, list);
  83.             }
  84.         }
  85.     } while (err == noErr);
  86. }
  87.  
  88. void
  89. AddDirectoryToList(long dirID, Handle list)
  90. {
  91.     long    loopy;
  92.     long    numberOfItems = GetHandleSize(list) / sizeof(long);
  93.     long*    dirs = (long*) *list;
  94.     
  95.     for (loopy = 0; loopy < numberOfItems; loopy++)
  96.     {
  97.         if (dirs[loopy] == dirID)
  98.         {
  99.             // Hmmm ... it's already there...
  100.             return;
  101.         }
  102.         if (dirs[loopy] > dirID)
  103.         {
  104.             Munger(list, loopy * sizeof(long), NIL, 0, &dirID, sizeof(long));
  105.             return;
  106.         }
  107.     }
  108.     
  109.     // If we got here, we add it to the end of the list
  110.     
  111.     Munger(list, numberOfItems * sizeof(long), NIL, 0, &dirID, sizeof(long));
  112. }
  113.  
  114. Boolean
  115. IsDirectoryInList(long dirID, Handle list)
  116. {
  117.     Boolean result;
  118.     long    numberOfItems = GetHandleSize(list) / sizeof(long);
  119.     long*    dirs = (long*) *list;
  120.  
  121.     HLock(list);
  122.     result = (bsearch(&dirID, dirs, numberOfItems, sizeof(long), DirIDCompare) != NIL);
  123.     HUnlock(list);
  124.     
  125.     return result;
  126. }
  127.  
  128. int
  129. DirIDCompare(const void* key, const void* data)
  130. {
  131.     const long* dirID = (const long*) key;
  132.     const long* listItem = (const long*) data;
  133.     
  134.     if (*dirID > *listItem)
  135.         return 1;
  136.     if (*dirID < *listItem)
  137.         return -1;
  138.     return 0;
  139. }
  140.  
  141. OSErr
  142. CatSearch(long* found, ...)
  143. {
  144.     static CSParam        pbFind;
  145.     static CInfoPBRec    pSpec1;
  146.     static CInfoPBRec    pSpec2;
  147.     static char            pFindBuffer[1024];
  148.     
  149.     static Boolean        subdirectorySearch = FALSE;
  150.     static long            searchDirectory;
  151.  
  152.     OSErr                result = noErr;
  153.     Boolean                initOnly = FALSE;
  154.     Boolean                restart;
  155.     
  156.     va_list                params;
  157.     int                    selector;
  158.     
  159.     
  160.     *found = 0;
  161.  
  162.     va_start(params, found);
  163.     restart = va_arg(params, int) != csContinue;
  164.     va_end(params);
  165.  
  166.     if (restart)
  167.     {
  168.         subdirectorySearch = FALSE;
  169.  
  170.         pbFind.ioNamePtr = NIL;
  171.         pbFind.ioVRefNum = 0;
  172.  
  173.         pbFind.ioMatchPtr = NIL;
  174.         pbFind.ioReqMatchCount = 0;
  175.  
  176.         pbFind.ioSearchBits = 0;
  177.  
  178.         pbFind.ioSearchInfo1 = &pSpec1;
  179.         pbFind.ioSearchInfo2 = &pSpec2;
  180.  
  181.         pbFind.ioSearchTime = 0;
  182.         pbFind.ioCatPosition.initialize = 0;
  183.  
  184.         pbFind.ioOptBuffer = pFindBuffer;
  185.         pbFind.ioOptBufSize = sizeof(pFindBuffer);
  186.  
  187.         memset(&pSpec1, 0, sizeof(pSpec1));
  188.         memset(&pSpec2, 0, sizeof(pSpec2));
  189.  
  190.         va_start(params, found);
  191.  
  192.         while ((result == noErr) && ((selector = va_arg(params, int)) != csEndList))
  193.         {
  194.             switch (selector)
  195.             {
  196.                 case csVRefNum:
  197.                 {
  198.                     pbFind.ioVRefNum = va_arg(params, short);
  199.                     break;
  200.                 }
  201.                 
  202.                 case csVNamePtr:
  203.                 {
  204.                     pbFind.ioNamePtr = va_arg(params, StringPtr);
  205.                     break;
  206.                 }
  207.                 
  208.                 case csMatchPtr:
  209.                 {
  210.                     pbFind.ioMatchPtr = va_arg(params, FSSpecPtr);
  211.                     pbFind.ioReqMatchCount = va_arg(params, long);
  212.                     break;
  213.                 }
  214.                 
  215.                 case csSearchTime:
  216.                 {
  217.                     pbFind.ioSearchTime = va_arg(params, long);
  218.                     break;
  219.                 }
  220.                 
  221.                 case csOptBuffer:
  222.                 {
  223.                     pbFind.ioOptBuffer = va_arg(params, Ptr);
  224.                     pbFind.ioOptBufSize = va_arg(params, long);
  225.                     break;
  226.                 }
  227.                 
  228.                 case csPartialName:
  229.                 {
  230.                     pbFind.ioSearchBits |= fsSBPartialName;
  231.                     pSpec1.hFileInfo.ioNamePtr = va_arg(params, StringPtr);
  232.                     break;
  233.                 }
  234.     
  235.                 case csFullName:
  236.                 {
  237.                     pbFind.ioSearchBits |= fsSBFullName;
  238.                     pSpec1.hFileInfo.ioNamePtr = va_arg(params, StringPtr);
  239.                     break;
  240.                 }
  241.     
  242.                 case csFlAttrib:
  243.                 {
  244.                     pbFind.ioSearchBits |= fsSBFlAttrib;
  245.                     pSpec1.hFileInfo.ioFlAttrib = va_arg(params, long);
  246.                     pSpec2.hFileInfo.ioFlAttrib = va_arg(params, long);
  247.                     break;
  248.                 }
  249.     
  250.                 case csFlFndrInfo:
  251.                 {
  252.                     pbFind.ioSearchBits |= fsSBFlFndrInfo;
  253.                     
  254.                     pSpec1.hFileInfo.ioFlFndrInfo.fdType = va_arg(params, OSType);
  255.                     pSpec1.hFileInfo.ioFlFndrInfo.fdCreator = va_arg(params, OSType);
  256.                     pSpec1.hFileInfo.ioFlFndrInfo.fdFlags = va_arg(params, unsigned short);
  257.                     pSpec1.hFileInfo.ioFlFndrInfo.fdLocation = va_arg(params, Point);
  258.                     pSpec1.hFileInfo.ioFlFndrInfo.fdFldr = va_arg(params, short);
  259.                     
  260.                     pSpec2.hFileInfo.ioFlFndrInfo.fdType = -1;
  261.                     pSpec2.hFileInfo.ioFlFndrInfo.fdCreator = -1;
  262.                     pSpec2.hFileInfo.ioFlFndrInfo.fdFlags = -1;
  263.                     *(long*) &pSpec2.hFileInfo.ioFlFndrInfo.fdLocation = -1;
  264.                     pSpec2.hFileInfo.ioFlFndrInfo.fdFldr = -1;
  265.                 
  266.                     break;
  267.                 }
  268.                     case csFInfoFDType:
  269.                     {
  270.                         pbFind.ioSearchBits |= fsSBFlFndrInfo;
  271.                         
  272.                         pSpec1.hFileInfo.ioFlFndrInfo.fdType = va_arg(params, OSType);
  273.                         pSpec2.hFileInfo.ioFlFndrInfo.fdType = -1;
  274.                         
  275.                         break;
  276.                     }
  277.                     case csFInfoFDCreator:
  278.                     {
  279.                         pbFind.ioSearchBits |= fsSBFlFndrInfo;
  280.                         
  281.                         pSpec1.hFileInfo.ioFlFndrInfo.fdCreator = va_arg(params, OSType);
  282.                         pSpec2.hFileInfo.ioFlFndrInfo.fdCreator = -1;
  283.                         
  284.                         break;
  285.                     }
  286.                     case csFInfoFDFlags:
  287.                     {
  288.                         pbFind.ioSearchBits |= fsSBFlFndrInfo;
  289.                         
  290.                         pSpec1.hFileInfo.ioFlFndrInfo.fdFlags = va_arg(params, unsigned short);
  291.                         pSpec2.hFileInfo.ioFlFndrInfo.fdFlags = -1;
  292.                         
  293.                         break;
  294.                     }
  295.                     case csFInfoFDLocation:
  296.                     {
  297.                         pbFind.ioSearchBits |= fsSBFlFndrInfo;
  298.                         
  299.                         pSpec1.hFileInfo.ioFlFndrInfo.fdLocation = va_arg(params, Point);
  300.                         SetPt(&pSpec2.hFileInfo.ioFlFndrInfo.fdLocation, -1, -1);
  301.                         
  302.                         break;
  303.                     }
  304.                     case csFInfoFDFldr:
  305.                     {
  306.                         pbFind.ioSearchBits |= fsSBFlFndrInfo;
  307.                         
  308.                         pSpec1.hFileInfo.ioFlFndrInfo.fdFldr = va_arg(params, short);
  309.                         pSpec2.hFileInfo.ioFlFndrInfo.fdFldr = -1;
  310.                         
  311.                         break;
  312.                     }
  313.     
  314.                 case csFlLgLen:
  315.                 {
  316.                     pbFind.ioSearchBits |= fsSBFlLgLen;
  317.             
  318.                     pSpec1.hFileInfo.ioFlLgLen = va_arg(params, long);
  319.                     pSpec2.hFileInfo.ioFlLgLen = va_arg(params, long);
  320.                     
  321.                     break;
  322.                 }
  323.                 
  324.                 case csFlPyLen:
  325.                 {
  326.                     pbFind.ioSearchBits |= fsSBFlPyLen;
  327.             
  328.                     pSpec1.hFileInfo.ioFlPyLen = va_arg(params, long);
  329.                     pSpec2.hFileInfo.ioFlPyLen = va_arg(params, long);
  330.                     
  331.                     break;
  332.                 }
  333.                 
  334.                 case csFlRLgLen:
  335.                 {
  336.                     pbFind.ioSearchBits |= fsSBFlRLgLen;
  337.             
  338.                     pSpec1.hFileInfo.ioFlRLgLen = va_arg(params, long);
  339.                     pSpec2.hFileInfo.ioFlRLgLen = va_arg(params, long);
  340.                     
  341.                     break;
  342.                 }
  343.                 
  344.                 case csFlRPyLen:
  345.                 {
  346.                     pbFind.ioSearchBits |= fsSBFlRPyLen;
  347.             
  348.                     pSpec1.hFileInfo.ioFlRPyLen = va_arg(params, long);
  349.                     pSpec2.hFileInfo.ioFlRPyLen = va_arg(params, long);
  350.                     
  351.                     break;
  352.                 }
  353.                 
  354.                 case csFlCrDat:
  355.                 {
  356.                     pbFind.ioSearchBits |= fsSBFlCrDat;
  357.             
  358.                     pSpec1.hFileInfo.ioFlCrDat = va_arg(params, unsigned long);
  359.                     pSpec2.hFileInfo.ioFlCrDat = va_arg(params, unsigned long);
  360.                     
  361.                     break;
  362.                 }
  363.                 
  364.                 case csFlMdDat:
  365.                 {
  366.                     pbFind.ioSearchBits |= fsSBFlMdDat;
  367.             
  368.                     pSpec1.hFileInfo.ioFlMdDat = va_arg(params, unsigned long);
  369.                     pSpec2.hFileInfo.ioFlMdDat = va_arg(params, unsigned long);
  370.                     
  371.                     break;
  372.                 }
  373.                 
  374.                 case csFlBkDat:
  375.                 {
  376.                     pbFind.ioSearchBits |= fsSBFlBkDat;
  377.             
  378.                     pSpec1.hFileInfo.ioFlBkDat = va_arg(params, unsigned long);
  379.                     pSpec2.hFileInfo.ioFlBkDat = va_arg(params, unsigned long);
  380.                     
  381.                     break;
  382.                 }
  383.                 
  384.                 case csFlXFndrInfo:
  385.                 {
  386.                     pbFind.ioSearchBits |= fsSBFlXFndrInfo;
  387.                     
  388.                     pSpec1.hFileInfo.ioFlXFndrInfo.fdIconID = va_arg(params, short);
  389.                     pSpec1.hFileInfo.ioFlXFndrInfo.fdScript = va_arg(params, short);
  390.                     pSpec1.hFileInfo.ioFlXFndrInfo.fdXFlags = va_arg(params, short);
  391.                     pSpec1.hFileInfo.ioFlXFndrInfo.fdComment = va_arg(params, short);
  392.                     pSpec1.hFileInfo.ioFlXFndrInfo.fdPutAway = va_arg(params, long);
  393.                     
  394.                     pSpec2.hFileInfo.ioFlXFndrInfo.fdIconID = -1;
  395.                     pSpec2.hFileInfo.ioFlXFndrInfo.fdScript = -1;
  396.                     pSpec2.hFileInfo.ioFlXFndrInfo.fdXFlags = -1;
  397.                     pSpec2.hFileInfo.ioFlXFndrInfo.fdComment = -1;
  398.                     pSpec2.hFileInfo.ioFlXFndrInfo.fdPutAway = -1;
  399.                 
  400.                     break;
  401.                 }
  402.                     case csFXInfoFDIconID:
  403.                     {
  404.                         pbFind.ioSearchBits |= fsSBFlXFndrInfo;
  405.                         
  406.                         pSpec1.hFileInfo.ioFlXFndrInfo.fdIconID = va_arg(params, short);
  407.                         pSpec2.hFileInfo.ioFlXFndrInfo.fdIconID = -1;
  408.                         
  409.                         break;
  410.                     }
  411.                     case csFXInfoFDScript:
  412.                     {
  413.                         pbFind.ioSearchBits |= fsSBFlXFndrInfo;
  414.                         
  415.                         pSpec1.hFileInfo.ioFlXFndrInfo.fdScript = va_arg(params, short);
  416.                         pSpec2.hFileInfo.ioFlXFndrInfo.fdScript = -1;
  417.                         
  418.                         break;
  419.                     }
  420.                     case csFXInfoFDXFlags:
  421.                     {
  422.                         pbFind.ioSearchBits |= fsSBFlXFndrInfo;
  423.                         
  424.                         pSpec1.hFileInfo.ioFlXFndrInfo.fdXFlags = va_arg(params, short);
  425.                         pSpec2.hFileInfo.ioFlXFndrInfo.fdXFlags = -1;
  426.                         
  427.                         break;
  428.                     }
  429.                     case csFXInfoFDComment:
  430.                     {
  431.                         pbFind.ioSearchBits |= fsSBFlXFndrInfo;
  432.                         
  433.                         pSpec1.hFileInfo.ioFlXFndrInfo.fdComment = va_arg(params, short);
  434.                         pSpec2.hFileInfo.ioFlXFndrInfo.fdComment = -1;
  435.                         
  436.                         break;
  437.                     }
  438.                     case csFXInfoFDPutAway:
  439.                     {
  440.                         pbFind.ioSearchBits |= fsSBFlXFndrInfo;
  441.                         
  442.                         pSpec1.hFileInfo.ioFlXFndrInfo.fdPutAway = va_arg(params, long);
  443.                         pSpec2.hFileInfo.ioFlXFndrInfo.fdPutAway = -1;
  444.                         
  445.                         break;
  446.                     }
  447.     
  448.                 case csFlParID:
  449.                 {
  450.                     pbFind.ioSearchBits |= fsSBFlParID;
  451.  
  452.                     pSpec1.hFileInfo.ioFlParID = va_arg(params, long);
  453.                     // what does spec2 get set to?
  454.  
  455.                     break;
  456.                 }
  457.                 
  458.                 case csNegate:
  459.                 {
  460.                     pbFind.ioSearchBits |= fsSBNegate;
  461.                     break;
  462.                 }
  463.     
  464.                 case csDrUsrWds:
  465.                 {
  466.                     pbFind.ioSearchBits |= fsSBDrUsrWds;
  467.  
  468.                     pSpec1.dirInfo.ioDrUsrWds.frRect = va_arg(params, Rect);
  469.                     pSpec1.dirInfo.ioDrUsrWds.frFlags = va_arg(params, short);
  470.                     pSpec1.dirInfo.ioDrUsrWds.frLocation = va_arg(params, Point);
  471.                     pSpec1.dirInfo.ioDrUsrWds.frView = va_arg(params, short);
  472.  
  473.                     SetRect(&pSpec2.dirInfo.ioDrUsrWds.frRect, -1, -1, -1, -1);
  474.                     pSpec2.dirInfo.ioDrUsrWds.frFlags = -1;
  475.                     SetPt(&pSpec2.dirInfo.ioDrUsrWds.frLocation, -1, -1);
  476.                     pSpec2.dirInfo.ioDrUsrWds.frView = -1;
  477.  
  478.                     break;
  479.                 }
  480.                     case csDInfoFRRect:
  481.                     {
  482.                         pbFind.ioSearchBits |= fsSBDrUsrWds;
  483.                         
  484.                         pSpec1.dirInfo.ioDrUsrWds.frRect = va_arg(params, Rect);
  485.                         SetRect(&pSpec2.dirInfo.ioDrUsrWds.frRect, -1, -1, -1, -1);
  486.                         
  487.                         break;
  488.                     }
  489.                     case csDInfoFRFlags:
  490.                     {
  491.                         pbFind.ioSearchBits |= fsSBDrUsrWds;
  492.                         
  493.                         pSpec1.dirInfo.ioDrUsrWds.frFlags = va_arg(params, short);
  494.                         pSpec2.dirInfo.ioDrUsrWds.frFlags = -1;
  495.                         
  496.                         break;
  497.                     }
  498.                     case csDInfoFRLocation:
  499.                     {
  500.                         pbFind.ioSearchBits |= fsSBDrUsrWds;
  501.                         
  502.                         pSpec1.dirInfo.ioDrUsrWds.frLocation = va_arg(params, Point);
  503.                         SetPt(&pSpec2.dirInfo.ioDrUsrWds.frLocation, -1, -1);
  504.                         
  505.                         break;
  506.                     }
  507.                     case csDInfoFRView:
  508.                     {
  509.                         pbFind.ioSearchBits |= fsSBDrUsrWds;
  510.                         
  511.                         pSpec1.dirInfo.ioDrUsrWds.frView = va_arg(params, short);
  512.                         pSpec2.dirInfo.ioDrUsrWds.frView = -1;
  513.                         
  514.                         break;
  515.                     }
  516.     
  517.     
  518.                 case csDrNmFls:
  519.                 {
  520.                     pbFind.ioSearchBits |= fsSBDrNmFls;
  521.  
  522.                     pSpec1.dirInfo.ioDrNmFls = va_arg(params, short);
  523.                     pSpec2.dirInfo.ioDrNmFls = va_arg(params, short);
  524.  
  525.                     break;
  526.                 }
  527.     
  528.                 case csDrCrDat:
  529.                 {
  530.                     pbFind.ioSearchBits |= fsSBDrCrDat;
  531.             
  532.                     pSpec1.dirInfo.ioDrCrDat = va_arg(params, unsigned long);
  533.                     pSpec2.dirInfo.ioDrCrDat = va_arg(params, unsigned long);
  534.                     
  535.                     break;
  536.                 }
  537.                 
  538.                 case csDrMdDat:
  539.                 {
  540.                     pbFind.ioSearchBits |= fsSBDrMdDat;
  541.             
  542.                     pSpec1.dirInfo.ioDrMdDat = va_arg(params, unsigned long);
  543.                     pSpec2.dirInfo.ioDrMdDat = va_arg(params, unsigned long);
  544.                     
  545.                     break;
  546.                 }
  547.                 
  548.                 case csDrBkDat:
  549.                 {
  550.                     pbFind.ioSearchBits |= fsSBDrBkDat;
  551.             
  552.                     pSpec1.dirInfo.ioDrBkDat = va_arg(params, unsigned long);
  553.                     pSpec2.dirInfo.ioDrBkDat = va_arg(params, unsigned long);
  554.                     
  555.                     break;
  556.                 }
  557.                 
  558.                 case csDrFndrInfo:
  559.                 {
  560.                     pbFind.ioSearchBits |= fsSBDrFndrInfo;
  561.  
  562.                     pSpec1.dirInfo.ioDrFndrInfo.frScroll = va_arg(params, Point);
  563.                     pSpec1.dirInfo.ioDrFndrInfo.frOpenChain = va_arg(params, long);
  564.                     pSpec1.dirInfo.ioDrFndrInfo.frComment = va_arg(params, short);
  565.                     pSpec1.dirInfo.ioDrFndrInfo.frPutAway = va_arg(params, long);
  566.  
  567.                     SetPt(&pSpec2.dirInfo.ioDrFndrInfo.frScroll, -1, -1);
  568.                     pSpec2.dirInfo.ioDrFndrInfo.frOpenChain = -1;
  569.                     pSpec2.dirInfo.ioDrFndrInfo.frComment = -1;
  570.                     pSpec2.dirInfo.ioDrFndrInfo.frPutAway = -1;
  571.  
  572.                     break;
  573.                 }
  574.                     case csDXInfoFRScroll:
  575.                     {
  576.                         pbFind.ioSearchBits |= fsSBDrFndrInfo;
  577.                         
  578.                         pSpec1.dirInfo.ioDrFndrInfo.frScroll = va_arg(params, Point);
  579.                         SetPt(&pSpec2.dirInfo.ioDrFndrInfo.frScroll, -1, -1);
  580.                         
  581.                         break;
  582.                     }
  583.                     case csDXInfoFROpenChain:
  584.                     {
  585.                         pbFind.ioSearchBits |= fsSBDrFndrInfo;
  586.                         
  587.                         pSpec1.dirInfo.ioDrFndrInfo.frOpenChain = va_arg(params, long);
  588.                         pSpec2.dirInfo.ioDrFndrInfo.frOpenChain = -1;
  589.                         
  590.                         break;
  591.                     }
  592.                     case csDXInfoFRComment:
  593.                     {
  594.                         pbFind.ioSearchBits |= fsSBDrFndrInfo;
  595.                         
  596.                         pSpec1.dirInfo.ioDrFndrInfo.frComment = va_arg(params, short);
  597.                         pSpec2.dirInfo.ioDrFndrInfo.frComment = -1;
  598.                         
  599.                         break;
  600.                     }
  601.                     case csDXInfoFRPutAway:
  602.                     {
  603.                         pbFind.ioSearchBits |= fsSBDrFndrInfo;
  604.                         
  605.                         pSpec1.dirInfo.ioDrFndrInfo.frPutAway = va_arg(params, long);
  606.                         pSpec2.dirInfo.ioDrFndrInfo.frPutAway = -1;
  607.                         
  608.                         break;
  609.                     }
  610.                 
  611.                 case csDrParID:
  612.                 {
  613.                     pbFind.ioSearchBits |= fsSBDrParID;
  614.  
  615.                     pSpec1.dirInfo.ioDrParID = va_arg(params, long);
  616.                     // what does spec2 get set to?
  617.  
  618.                     break;
  619.                 }
  620.                 
  621.                 case csSearchInDirectory:
  622.                 {
  623.                     subdirectorySearch = TRUE;
  624.                     
  625.                     searchDirectory = va_arg(params, long);
  626.                     
  627.                     break;
  628.                 }
  629.                 
  630.                 case csContinue:
  631.                 {
  632.                     // csContinue found in the middle of a list of parameters.
  633.                     // It needs to be at the beginning.
  634.                     result = paramErr;
  635.                     break;
  636.                 }
  637.                 
  638.                 case csInitOnly:
  639.                 {
  640.                     initOnly = TRUE;
  641.                     break;
  642.                 }
  643.                 
  644.                 default:
  645.                 {
  646.                     DebugStr("\pCatSearch: received an unknown selector!");
  647.                     result = paramErr;
  648.                     break;
  649.                 }
  650.             }
  651.         }
  652.         
  653.         va_end(params);
  654.     }
  655.     
  656.     if (result == noErr)
  657.     {
  658.         if (pbFind.ioNamePtr == NIL && pbFind.ioVRefNum >= 0)
  659.             result = paramErr;
  660.         
  661.         if (pbFind.ioMatchPtr == NIL || pbFind.ioReqMatchCount <= 0)
  662.             result = paramErr;
  663.         
  664.         if (pbFind.ioSearchBits == 0)
  665.             result = paramErr;
  666.     }
  667.  
  668.     if (result == noErr && !initOnly)
  669.     {
  670.         if (subdirectorySearch)
  671.             result = PBCatSearchIn(&pbFind, searchDirectory);
  672.         else
  673.             result = PBCatSearchSync(&pbFind);
  674.  
  675.         if (result == noErr || result == eofErr)
  676.             *found = pbFind.ioActMatchCount;
  677.     }
  678.     
  679.     return result;
  680. }
  681.  
  682.